package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

type Client struct {
	addr    string
	account string
	passwd  string
	appcode string

	token string
}

func NewClient(addr string, account string, passwd string, appcode string) (*PayClient, error) {
	client := &PayClient{
		addr:    addr,
		account: account,
		passwd:  passwd,
		appcode: appcode,
	}

	token, err := client.Signin()
	if err != nil {
		return nil, err
	}

	client.token = token
	return client, nil
}

type Response struct {
	Action  string
	Code    string
	Data    interface{}
	Message string
}

func (client *PayClient) ActionByPost(params url.Values, result interface{}) error {
	params.Set("AppCode", client.appcode)
	body := bytes.NewBufferString(params.Encode())

	r, err := http.NewRequest(http.MethodPost, client.addr, body)
	if err != nil {
		return fmt.Errorf("new  request failed: %s", err.Error())
	}

	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	r.Header.Set("Token", client.token)

	handler := &http.Client{}
	resp, err := handler.Do(r)
	if err != nil {
		return fmt.Errorf("do action failed: %s", err.Error())

	}
	defer resp.Body.Close()

	bodyBuf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("real resp body failed: %s", err.Error())
	}

	data := new(Response)
	data.Data = result

	err = json.Unmarshal(bodyBuf, data)
	if err != nil {
		return fmt.Errorf("unmarshal failed: %s", err.Error())
	}

	if data.Code != "ok" {
		return fmt.Errorf("%s:%s", data.Code, data.Message)
	}
	return nil
}
